package com.lingnan.config;



import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

import com.lingnan.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;


/**
 * mvc全局配置
 *
 * @author hhj
 * @date 2024/11/16
 */
/**
 * 全局Web MVC配置类，继承WebMvcConfigurationSupport以自定义Spring MVC配置
 * 主要功能：
 * 1. 配置自定义的HTTP消息转换器
 * 2. 添加全局拦截器
 */
@Configuration
public class GlobalConfig extends WebMvcConfigurationSupport {

    /**
     * 配置HTTP消息转换器列表
     * 添加自定义的Jackson消息转换器用于JSON序列化/反序列化
     * @param converters 原始转换器列表，由父类提供
     */
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        // 添加自定义的Jackson消息转换器
        converters.add(mappingJackson2HttpMessageConverter());
    }

    /**
     * 添加拦截器配置
     * 注册登录拦截器并设置拦截所有请求路径
     * @param registry 拦截器注册表，用于添加和管理拦截器
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 添加登录拦截器并配置拦截路径
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**");
    }

    /**
     * 创建并配置自定义的Jackson消息转换器
     * 配置说明：
     * 1. 禁用空Bean序列化失败功能
     * 2. 设置只序列化非空字段
     * 3. 将Long类型序列化为字符串，解决JavaScript精度丢失问题
     * @return 配置好的MappingJackson2HttpMessageConverter实例
     */
    private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 配置Jackson序列化特性
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        
        // 配置Long类型序列化为字符串，解决JavaScript精度丢失问题
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        
        return new MappingJackson2HttpMessageConverter(objectMapper);
    }

}

